package cn.xeblog.plugin.tools.browser2.resize;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.xeblog.plugin.cache.DataCache;
import cn.xeblog.plugin.enums.Command;
import cn.xeblog.plugin.tools.browser.config.BrowserConfig;
import cn.xeblog.plugin.tools.browser.core.UserAgent;
import cn.xeblog.plugin.tools.browser.ui.SettingUI;
import cn.xeblog.plugin.tools.browser2.utils.BrowserSettingUtil;
import cn.xeblog.plugin.tools.browser2.utils.EngineUtil;
import cn.xeblog.plugin.util.NotifyUtils;
import com.intellij.ide.ui.laf.darcula.DarculaLaf;
import com.intellij.openapi.ui.ComboBox;
import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.engine.Engine;
import com.teamdev.jxbrowser.navigation.Navigation;
import com.teamdev.jxbrowser.ui.Size;
import com.teamdev.jxbrowser.view.swing.BrowserView;
import com.teamdev.jxbrowser.zoom.ZoomLevel;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

/**
 * @author eleven
 * @date 2024/12/19 10:48
 * @apiNote
 */
@Slf4j
public class JxBrowserUI extends JPanel {

    private String jxBrowserLicense;

    private Engine engine;

    private Browser browser;
    private Navigation navigation;

    private WindowMode windowMode;

    private UserAgent userAgent;

    private JComponent browserUI;

    private String lastUrl;

    private  BrowserView browserView;


    private JTextField urlField;

    private JTextField sizeField;

    private BrowserConfig browserConfig;

    private enum WindowMode {
        SMALL("S", 200, 250),
        MEDIUM("M", 400, 300);

        @Getter
        String name;

        @Getter
        int width;

        @Getter
        int height;

        WindowMode(String name, int width, int height) {
            this.name = name;
            this.width = width;
            this.height = height;
        }

        public static WindowMode getMode(String name) {
            for (WindowMode mode : values()) {
                if (mode.getName().equals(name)) {
                    return mode;
                }
            }
            return WindowMode.SMALL;
        }
    }

    public JxBrowserUI(String jxBrowserLicense) {
        this.jxBrowserLicense = jxBrowserLicense;
        this.windowMode = WindowMode.SMALL;
        this.userAgent = UserAgent.WINDOWS;
        this.browserUI = new JPanel();
        browserConfig = DataCache.browserConfig;
        this.urlField = new JTextField(browserConfig.getHomePage());
        initPanel();
    }

    private void initBrowser(String jxBrowserLicense) {
        // 初始化JxBrowser引擎
        engine = EngineUtil.engine(jxBrowserLicense);
        browser = engine.newBrowser();
        addBrowserPanel();
    }

    private boolean isDarkTheme() {
        LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
        NotifyUtils.info("当前主题：" , lookAndFeel.getName());
        return lookAndFeel instanceof DarculaLaf;
    }

    private void addBrowserPanel() {
        BrowserSettingUtil.setPopupCallback(browser, browserUI, urlField);
        isDarkTheme();
        log.info("this panel width height: {}, {}", this.getWidth(), this.getHeight());
        log.info("this browser panel width height: {}, {}", this.getWidth(), this.getHeight());
        // 创建BrowserView，用于在Swing中展示浏览器内容
        browserView = BrowserView.newInstance(browser);
        browserView.setPreferredSize(new Dimension(400, 300));
        // 将BrowserView添加到JPanel中
        browserUI.add(browserView, BorderLayout.CENTER);
        navigation = browser.navigation();
        browser.navigation().loadUrl(urlField.getText());

    }

    private Integer parseInput(String str, Integer defaultValue, Integer parentMaxSize) {
        str = str.trim();
        if (NumberUtil.isNumber(str)) {
            try {
                return Math.min(Math.abs(Integer.parseInt(str)), parentMaxSize);
            } catch ( Exception e) {
                NotifyUtils.error("XeChat", "用户输入有误，使用默认数字" + defaultValue);
            }
        }
        return defaultValue;
    }

    public void initPanel() {
        removeAll();

        String url = browserConfig.getHomePage();
        if (lastUrl != null) {
            url = lastUrl;
        }

        if (this.browser != null) {
            this.browser.close();
        }
        initBrowser(jxBrowserLicense);
        this.browser.userAgent(userAgent.toString());
        urlField = new JTextField(url);
        resize();
        browserUI.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent e) {
                browserView.setPreferredSize(new Dimension(browserUI.getWidth(), browserUI.getHeight()));
                browserView.updateUI();
            }
        });
        Dimension buttonDimension = new Dimension(50, 25);
        Box hbox = Box.createHorizontalBox();

        JButton exitButton = new JButton("x");
        exitButton.setToolTipText("退出");
        exitButton.setPreferredSize(buttonDimension);
        exitButton.addActionListener(l -> Command.OVER.exec());
        hbox.add(exitButton);

        JButton settingButton = new JButton("✡");
        settingButton.setToolTipText("设置");
        settingButton.setPreferredSize(buttonDimension);
        settingButton.addActionListener(l -> new SettingUI().show());
        hbox.add(settingButton);

        JButton homeButton = new JButton("♨");
        homeButton.setToolTipText("主页");
        homeButton.setPreferredSize(buttonDimension);
        homeButton.addActionListener(l -> navigation.loadUrl(browserConfig.getHomePage()));
        hbox.add(homeButton);

        JButton backButton = new JButton("←");
        backButton.setToolTipText("后退");
        backButton.setPreferredSize(buttonDimension);
        backButton.addActionListener(l -> navigation.goBack());
        hbox.add(backButton);

        JButton forwardButton = new JButton("→");
        forwardButton.setToolTipText("前进");
        forwardButton.setPreferredSize(buttonDimension);
        forwardButton.addActionListener(l -> navigation.goForward());
        hbox.add(forwardButton);

        JButton refreshButton = new JButton("⟳");
        refreshButton.setToolTipText("刷新");
        refreshButton.setPreferredSize(buttonDimension);
        refreshButton.addActionListener(l -> navigation.reload());
        hbox.add(refreshButton);
        hbox.add(urlField);

        JPanel urlPanel = new JPanel();
        urlPanel.add(hbox);

        Box h2Box = Box.createHorizontalBox();
        h2Box.add(new JLabel("Size："));
        sizeField = new JTextField(StrUtil.format("{}:{}", browserView.getWidth(), browserView.getHeight()));
        h2Box.add(sizeField);
        sizeField.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                    String text = sizeField.getText();
                    if (!text.contains(":")) {
                        NotifyUtils.error("XeChat","请输入正确的大小，例如：100:200");
                        return;
                    }
                    String[] split = text.split(":");
                    int width = parseInput(split[0], browserView.getWidth(), browserUI.getWidth());
                    int height = parseInput(split[1], browserView.getHeight(), browserUI.getHeight());
                    browserView.setPreferredSize(new Dimension(width, height));
                    browserView.updateUI();
                    browserUI.updateUI();
                    log.info("resize：{}:{}, realSize: {}:{}", width, height, browserView.getWidth(), browserView.getHeight());
                }
            }
        });
        h2Box.add(new JLabel("Window："));
        ComboBox windowModeBox = new ComboBox();
        windowModeBox.setPreferredSize(buttonDimension);
        for (WindowMode mode : WindowMode.values()) {
            windowModeBox.addItem(mode.getName());
        }
        windowModeBox.setSelectedItem(windowMode.getName());
        windowModeBox.addItemListener(l -> {
            windowMode = WindowMode.getMode(l.getItem().toString());
            resize();
            updateUI();
        });
        h2Box.add(windowModeBox);

        h2Box.add(Box.createHorizontalStrut(5));
        h2Box.add(new JLabel("UA："));
        ComboBox uaBox = new ComboBox();
        uaBox.setPreferredSize(new Dimension(100, 30));
        for (UserAgent userAgent : UserAgent.values()) {
            uaBox.addItem(userAgent.getName());
        }
        uaBox.setSelectedItem(userAgent.getName());
        uaBox.addItemListener(l -> {
            userAgent = UserAgent.getUserAgent(l.getItem().toString());
            browser.userAgent(userAgent.toString());
            navigation.reload();
        });
        h2Box.add(uaBox);

        h2Box.add(Box.createHorizontalStrut(5));
        h2Box.add(new JLabel("Zoom："));
        JTextField zoomLevelField = new JTextField("0.0");
        zoomLevelField.setPreferredSize(new Dimension(50, 30));
        zoomLevelField.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                    String value = zoomLevelField.getText();
                    if (NumberUtil.isNumber(value)) {
                        double zoom = Double.parseDouble(value);
                        browser.zoom().level(ZoomLevel.of(zoom));;
                    }
                }
            }
        });
        h2Box.add(zoomLevelField);

        JPanel bottomPanel = new JPanel();
        bottomPanel.add(h2Box);

        setLayout(new BorderLayout());
        add(urlPanel, BorderLayout.NORTH);
        add(browserUI, BorderLayout.CENTER);
        add(bottomPanel, BorderLayout.SOUTH);
        add(Box.createHorizontalStrut(10), BorderLayout.EAST);

        updateUI();

        urlField.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                    String url = urlField.getText();
                    if (!StrUtil.startWithAny(url, "https://", "http://")) {
                        url = "https://" + url;
                    }
                    navigation.loadUrl(url);
                }
            }
        });
    }

    private void resize() {
        int width = this.windowMode.getWidth();
        int height = this.windowMode.getHeight();

        urlField.setPreferredSize(new Dimension(width * 2 / 3, 30));
        urlField.updateUI();

        Dimension browserDimension = new Dimension(width, height);
        browserUI.setMinimumSize(null);
        browserUI.setPreferredSize(null);
        if (windowMode == WindowMode.SMALL) {
            browserUI.setPreferredSize(browserDimension);
            browserView.setPreferredSize(browserDimension);
        } else {
            browserUI.setMinimumSize(browserDimension);
            browserView.setPreferredSize(browserDimension);
        }
    }

    public void close() {
        this.browser.close();
        this.engine.close();
    }
}
